/* Copyright 2001,2002,2003 NAH6 BV
 * All Rights Reserved
 *
 *  $Header: /var/lib/cvs/secphone/ui/userdata/UserdataHandler.h,v 1.5 2003/11/21 12:39:24 itsme Exp $
 *
 *
 */


#ifndef __USERDATAHANDLER_H__
#include <windows.h>

#include <vector>
#include <map>
#include "vectorutils.h"

typedef int UDCLIENTID;

class UDClientHandler {
public:
    virtual bool HandleUserdataMessage(const ByteVector& data)=0;
    virtual bool StopSending()=0;
};

typedef std::map<UDCLIENTID, UDClientHandler*> ClientToUDMap;
typedef std::map<UDCLIENTID, ByteVector> ClientToMsgMap;
typedef std::map<UDCLIENTID, int> ClientToCountMap;
typedef std::map<UDCLIENTID, DWORD> ClientToTimerMap;
typedef std::map<DWORD,UDCLIENTID> TimerToClientMap;

class CDialog;



class UserdataHandler {
public:
    UserdataHandler(CDialog& dlg);
    virtual ~UserdataHandler();

    bool HandleUserData(DWORD dwId, const ByteVector& data);

    bool SendSingleMessage(const ByteVector& data);
    bool SendStateMessage(UDCLIENTID client, const ByteVector& data, int interval=1000, int count=-1);
    bool StopStateMessage(UDCLIENTID client);

    bool UnRegisterUserdataHandler(UDCLIENTID client);
    bool RegisterUserdataHandler(UDCLIENTID client, UDClientHandler* handler);

    void EnableSecureMode();

    void StopAll();

protected:
    static void CALLBACK staticTimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime);
    void TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime);

private:
    ClientToUDMap m_udHandlers;

    ClientToMsgMap m_udClientMessages;
    ClientToCountMap m_udClientMessageCount;
    ClientToTimerMap m_udClientTimers;
    TimerToClientMap m_udTimerClient;

    bool m_bUserdataChannelIsSecure;

    CDialog& m_dlg;

    CRITICAL_SECTION m_lock;
};

//  bit7   : 1=message may only be transmitted over a secure channel
//  bit6-4 : clientid
//  bit3-0 : messageid

#define isSecureChannelMessage(m) (((m)&0x80)!=0)
#define UD_CLIENT(m)  ((UDCLIENTID)((m)>>4)&0x07)
#define UD_MESSAGE(m)  ((m)&0x0f)

#define UDMSG(client, id) ((client)<<4 | (id))
#define UDSMSG(client, id) (0x80 | ((client)<<4) | (id))

#define UDCLT_DIFFIEHELLMAN 0
#define DHMSG_START     UDMSG(UDCLT_DIFFIEHELLMAN, 1)
#define DHMSG_CONTINUE  UDMSG(UDCLT_DIFFIEHELLMAN, 2)
#define DHMSG_END       UDMSG(UDCLT_DIFFIEHELLMAN, 3)
#define DHMSG_REJECT    UDMSG(UDCLT_DIFFIEHELLMAN, 4)
#define DHMSG_CONFIRM   UDMSG(UDCLT_DIFFIEHELLMAN, 5)

#define UDCLT_PINGER     7
#define PINGMSG_PING    UDMSG(UDCLT_PINGER, 1)
#define PINGMSG_PONG    UDMSG(UDCLT_PINGER, 2)

// todo: rename this to 'callctrl'
#define UDCLT_AUTOANSWER 6
#define AAMSG_ANSWERED   UDMSG(UDCLT_AUTOANSWER, 1)
#define AAMSG_WAITING    UDMSG(UDCLT_AUTOANSWER, 2)
#define AAMSG_HANGUP     UDMSG(UDCLT_AUTOANSWER, 3)

// this is a secure channel client
#define UDCLT_LICENSE    8
#define LCMSG_LICENSEHASH UDMSG(UDCLT_LICENSE, 1)

#define __USERDATAHANDLER_H__
#endif
